package one.stand.interceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import one.stand.aop.ApiController;
import one.stand.entity.TokenEntity;
import one.stand.enums.ResultEnum;
import one.stand.exception.*;
import one.stand.feign.CrmFegin;
import one.stand.feign.LoginFegin;
import one.stand.model.ResultModel;
import one.stand.request.BusinessCardRequest;
import one.stand.request.TokenRequest;
import one.stand.util.IpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Administrator
 */
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

    protected static final Logger log = LoggerFactory.getLogger(LoginInterceptor.class);
    @Autowired
    @Lazy
    private CrmFegin crmFegin;
    @Autowired
    @Lazy
    private LoginFegin loginFegin;

    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        httpServletResponse.setHeader("Content-type", "application/json;charset=UTF-8");
        StringBuffer requestURL = httpServletRequest.getRequestURL();
        log.info("前置拦截器1 preHandle： 请求的uri为：" + requestURL.toString());
        try {
            String ip = IpUtil.getIpAddr(httpServletRequest);
            String token = httpServletRequest.getHeader("token");
            TokenRequest request = new TokenRequest();
            request.setIp(ip);
            request.setToken(token);
            if (o instanceof HandlerMethod) {
                HandlerMethod h = (HandlerMethod) o;
                ApiController apiController = h.getMethodAnnotation(ApiController.class);
                if (apiController != null) {
                    //验证是否需要进行登陆校验
                    if (apiController.isLogin()) {
                        if (StringUtils.isEmpty(token)) {
                            //未获取到token抛出异常
                            throw new LoginException("token请求头未设置");
                        }
                        ResultModel<Boolean> result = loginFegin.loginVerification(token);
                        if (result == null) {
                            throw new LoginException("校验token失败");
                        } else if (result.getData() == null || !result.getData()) {
                            throw new LoginException("校验token失败: " + result.getMessage());
                        }
                        TokenEntity tokenEntity = loginFegin.getLoginInfo(token).getData();
                        if (null == token) {
                            //未获取到token抛出异常
                            throw new LoginException("缓存token信息不存在，请检查是否登录?");
                        }
                        if (apiController.company()) {
                            if (null == tokenEntity.getCId()) {
                                throw new CompanyException("Token缓存信息的公司ID为空");
                            }
                        }
                        if (apiController.card()) {
                            if (null == tokenEntity.getMyCardId()) {
                                throw new CardException("Token缓存信息的卡片id为空");
                            }
                            ResultModel resultModel = crmFegin.verifyExpired(new BusinessCardRequest() {{
                                setCardId(tokenEntity.getMyCardId());
                            }});
                            log.info("名片服务验证：{}", JSON.toJSONString(resultModel));
                            if (!resultModel.isSuccess()) {
                                throw new CardNumServiceException("卡片服务校验失败:" + resultModel.getMessage());
                            }
                        }
                        if (apiController.isBoss()) {
                            if (null == tokenEntity.getRoleId() || tokenEntity.getRoleId() <= 0) {
                                throw new BossException("Token缓存信息的roleId为空或者不合法，需要校验是否boss");
                            }
                        }
                        BeanUtils.copyProperties(tokenEntity, request);
                        if (apiController.isParam()) {
                            Object object = httpServletRequest.getAttribute("request");
                            JSONObject data;
                            if (null == object) {
                                data = new JSONObject();
                            } else {
                                data = (JSONObject) JSONObject.toJSON(object);
                            }
                            data.put("token", token);
                            data.put("id", request.getId());
                            data.put("ip", request.getIp());
                            data.put("cId", request.getCId());
                            data.put("roleId", request.getRoleId());
                            data.put("myCardId", request.getMyCardId());
                            data.put("loginProgramName", request.getLoginProgramName());
                            data.put("logintime", request.getLogintime());
                            data.put("companyKey", request.getCompanyKey());
                            httpServletRequest.setAttribute("request", data.toJavaObject(apiController.paramClass()));
                        }
                    }


                }
            }
            httpServletRequest.setAttribute("tokenRequest", request);
            return true;
        } catch (LoginException l) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.NO_LOGIN, l.getMessage());
        } catch (CompanyException ce) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.NO_COMPANY, ce.getMessage());
        } catch (CardException cee) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.NO_ROLE, cee.getMessage());
        } catch (CardNumServiceException cnse) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.CARD_OVERDUE, cnse.getMessage());
        } catch (BossException be) {
            ResultModel.returnJson(httpServletResponse, ResultEnum.NO_BOSS, be.getMessage());
        } catch (Exception e) {
            log.error("登录拦截[异常]", e);
            ResultModel.returnJson(httpServletResponse, ResultEnum.SYS_ERROR, e.getMessage());
        }
        return false;
    }
}
